-- 元表
--[[
Metamethods：
有点像C++里面的运算符重载。有些固定的项目设置之后，可以运用操作符，比如[]，加减乘除等等
__index
__newindex
__add
__sub
__mul
__concat
__call
__tostring
]]

-- 可以把metatable想象为一种Helper类。是附加到一个table上去使用
local meta = {}
local vector3d = {}

-- 为一个表增加功能（这其实相当于类了）
-- 也可以使用 vector3d["new"] = function(x,y,z) 创建
function vector3d.new(x,y,z)
    local v = {x = x, y = y, z = z}
    -- 这里等于把项目绑定到metatable中
    setmetatable(v, meta)
    return v
end

-- 这里就是绑定的格式。使用+运算符，在metatable里面使用__add = vector3d.add
function vector3d.add(v1, v2)
    return vector3d.new(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
end
meta.__add = vector3d.add

-- 绑定tostring
function vector3d.tostring(v)
    return "("..v.x..","..v.y..","..v.z..")"
end
meta.__tostring = vector3d.tostring

local position = vector3d.new(5.0, 5.0, 5.0)
local velocity = vector3d.new(10.0, -3.5, 0.0)

-- 这行需要metatable中拥有__add才不会出错。
local result = velocity + position
-- 需要拥有__tostring才能打印值，而不是table地址。
print(result)